/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.zookeeper;

import org.apache.yetus.audience.InterfaceAudience;

/**接口类型，其定义了process方法，需子类实现
 * <br/>This interface specifies the public interface an event handler class must
 * implement. A ZooKeeper client will get various events from the ZooKeeper
 * server it connects to. An application using such a client handles these
 * events by registering a callback object with the client. The callback object
 * is expected to be an instance of a class that implements Watcher interface.
 *
 */
@InterfaceAudience.Public
public interface Watcher {

    /**接口类型，Watcher的内部类，表示事件代表的状态，无任何方法
     * <br/>This interface defines the possible states an Event may represent
     */
    @InterfaceAudience.Public
    interface Event {

        /**KeeperState是一个枚举类，其定义了在事件发生时Zookeeper所处的各种状态，其还定义了一个从整形值返回对应状态的方法fromInt
         * <br/>Enumeration of states the ZooKeeper may be at the event
         */
        @InterfaceAudience.Public
        enum KeeperState {
            /**未知状态，不再使用，服务器不会产生此状态
             */
            @Deprecated
            Unknown(-1),

            /**客户端处于断开状态-它没有连接到集成中的任何服务器
             * <br/>The client is in the disconnected state - it is not connected to any server in the ensemble.
             */
            Disconnected(0),

            /**未同步连接，不再使用，服务器不会产生此状态
             */
            @Deprecated
            NoSyncConnected(1),

            /**客户端处于连接状态-它连接到集成中的服务器(在创建ZooKeeper客户端时主机连接参数中指定的服务器之一)
             * <br/>The client is in the connected state - it is connected
             * to a server in the ensemble (one of the servers specified
             * in the host connection parameter during ZooKeeper client creation).
             */
            SyncConnected(3),

            /**认证失败状态
             */
            AuthFailed(4),

            /**客户端连接到一个只读服务器，即当前没有连接到大多数服务器的服务器。接收到此状态后，只允许进行读操作。此状态仅为只读客户端生成，因为读写客户端不允许连接到r/o服务器
             * <br/>The client is connected to a read-only server, that is the
             * server which is not currently connected to the majority.
             * The only operations allowed after receiving this state is
             * read operations.
             * This state is generated for read-only clients only since
             * read/write clients aren't allowed to connect to r/o servers.
             */
            ConnectedReadOnly(5),

            /**SASL认证通过状态
             * <br/>SaslAuthenticated: used to notify clients that they are SASL-authenticated,
             * so that they can perform Zookeeper actions with their SASL-authorized permissions.
             */
            SaslAuthenticated(6),

            /**服务集群已过期此会话。ZooKeeper客户端连接(会话)不再有效。你必须创建一个新的客户端连接(实例化一个新的zookeeper实例)，如果你想要访问集成
             * <br/>The serving cluster has expired this session. The ZooKeeper
             * client connection (the session) is no longer valid. You must
             * create a new client connection (instantiate a new ZooKeeper
             * instance) if you with to access the ensemble.
             */
            Expired(-112),

            /**客户端已关闭。此状态永远不会由服务器生成，而是在客户端调用ZooKeeper.close()或ZooKeeper.close(int)时本地生成
             * <br/>The client has been closed. This state is never generated by
             * the server, but is generated locally when a client calls
             * {@link ZooKeeper#close()} or {@link ZooKeeper#close(int)}
             */
            Closed(7);

            /**代表状态的整形值
             *
             */
            private final int intValue;     // Integer representation of value
            // for sending over wire

            KeeperState(int intValue) {
                this.intValue = intValue;
            }

            public int getIntValue() {
                return intValue;
            }

            /**从整形值构造相应的状态
             * @param intValue
             * @return
             */
            public static KeeperState fromInt(int intValue) {
                switch (intValue) {
                case -1:
                    return KeeperState.Unknown;
                case 0:
                    return KeeperState.Disconnected;
                case 1:
                    return KeeperState.NoSyncConnected;
                case 3:
                    return KeeperState.SyncConnected;
                case 4:
                    return KeeperState.AuthFailed;
                case 5:
                    return KeeperState.ConnectedReadOnly;
                case 6:
                    return KeeperState.SaslAuthenticated;
                case -112:
                    return KeeperState.Expired;
                case 7:
                    return KeeperState.Closed;

                default:
                    throw new RuntimeException("Invalid integer value for conversion to KeeperState");
                }
            }
        }

        /**EventType是一个枚举类，其定义了事件的类型（如创建节点、删除节点等事件），同时，其还定义了一个从整形值返回对应事件类型的方法fromInt
         * <br/>Enumeration of types of events that may occur on the ZooKeeper
         */
        @InterfaceAudience.Public
        enum EventType {
            /**无
             *
             */
            None(-1),
            /**创建节点
             *
             */
            NodeCreated(1),
            /**删除节点
             *
             */
            NodeDeleted(2),
            /**节点数据改变
             *
             */
            NodeDataChanged(3),
            /**子节点变化
             *
             */
            NodeChildrenChanged(4),
            /**删除watch
             *
             */
            DataWatchRemoved(5),
            /**子节点删除watch
             *
             */
            ChildWatchRemoved(6),
            PersistentWatchRemoved (7);

            /**代表事件类型的整形
             *
             */
            private final int intValue;     // Integer representation of value
            // for sending over wire

            EventType(int intValue) {
                this.intValue = intValue;
            }

            public int getIntValue() {
                return intValue;
            }

            /**从整形构造相应的事件
             * @param intValue
             * @return
             */
            public static EventType fromInt(int intValue) {
                switch (intValue) {
                case -1:
                    return EventType.None;
                case 1:
                    return EventType.NodeCreated;
                case 2:
                    return EventType.NodeDeleted;
                case 3:
                    return EventType.NodeDataChanged;
                case 4:
                    return EventType.NodeChildrenChanged;
                case 5:
                    return EventType.DataWatchRemoved;
                case 6:
                    return EventType.ChildWatchRemoved;
                case 7:
                    return EventType.PersistentWatchRemoved;

                default:
                    throw new RuntimeException("Invalid integer value for conversion to EventType");
                }
            }
        }

    }

    /**
     * Enumeration of types of watchers
     */
    @InterfaceAudience.Public
    enum WatcherType {
        Children(1),
        Data(2),
        Any(3);

        // Integer representation of value
        private final int intValue;

        WatcherType(int intValue) {
            this.intValue = intValue;
        }

        public int getIntValue() {
            return intValue;
        }

        public static WatcherType fromInt(int intValue) {
            switch (intValue) {
            case 1:
                return WatcherType.Children;
            case 2:
                return WatcherType.Data;
            case 3:
                return WatcherType.Any;

            default:
                throw new RuntimeException("Invalid integer value for conversion to WatcherType");
            }
        }
    }

    /**代表了实现Watcher接口时必须实现的的方法，即定义进行处理，WatchedEvent表示观察的事件
     * @param event
     */
    void process(WatchedEvent event);

}
